package cc.plumgo.ss.yo.entity;

import java.util.Random;

import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;

import cc.plumgo.j2me.utils.CustomRole;
import cc.plumgo.ss.core.Constants;

public class Enemy extends CustomRole {
	public static final int ENM_WALK = 0;
	public static final int ENM_ATTACK = 1;
	public static final int ENM_ATTACKED = 2;
	public static final int ENM_DIE = 3;

	protected int initPosX;
	protected int initPosY;

	protected boolean finding;
	protected boolean attackedFlag;
	protected boolean deadFlag;

	protected int manDis;
	protected int stopTime;
	protected boolean stopFlag;

	protected int attackFreq;
	protected Random random;
	protected int tmpState;
	protected int type;
	protected int attackMoveSpeed;
	protected int walkSpeed;
	protected int spriteDir;
	protected Item item;
	
	public Enemy(int type, int x, int y) {
		super(1);
		state = ENM_WALK;
		totalState = 4;
		initPosX = x;
		initPosY = y;
		posX = x;
		posY = y;
		finding = true;
		this.type = type;
		attackDis = Constants.ENM_ATTACK_DIS[type];
		attackHarm = Constants.ENM_ATTACK_HARM[type];
		attackFreq = Constants.ENM_ATTACK_FREQ[type];
		attackMoveSpeed = Constants.ENM_ATTACK_MOVE_SPEED[type];
		walkSpeed = Constants.ENM_WALK_SPEED[type];
		blood = Constants.ENM_BLOOD[type];
		spriteDir = Constants.ENM_SPRITE_DIR[type];
		stopTime = 0;
		stopFlag = false;
		random = new Random();
		try {
			sprites = new Sprite[totalState];
			frameNums = new int[totalState];
			Image img = null;

			for (int i = 0; i < totalState; i++) {
				img = Image.createImage(Constants.ENM_SPRITE_IMGS[type][i]);
				int w = Constants.ENM_SPRITE_W[type][i];
				int h = Constants.ENM_SPRITE_H[type][i];
				sprites[i] = new Sprite(img, w, h);
				sprites[i].setRefPixelPosition(w / 2, h / 2);
				frameNums[i] = -1;
				sprites[i].setVisible(false);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		updateAllPositions();
	}

	public void updateDirectX() {
		int tmpX = initPosX;

		switch (direct) {
		case DIR_LEFT: {
			tmpX = posX + walkSpeed;
			if (tmpX > initPosX + Constants.ENM_WALK_RANGE_X) {
				setDirect(DIR_RIGHT);
			}
			break;
		}
		case DIR_RIGHT: {
			tmpX = posX - walkSpeed;
			if (tmpX < initPosX - Constants.ENM_WALK_RANGE_X) {
				setDirect(DIR_LEFT);
			}
			break;
		}
		}
		posX = tmpX;
	}

	public void stop(int time, int state) {
		if (!stopFlag) {
			stopTime = time;
			tmpState = state;
			stopFlag = true;
			state = ENM_WALK;
		}
	}

	public int getType() {
		return type;
	}

	public void setLayer(LayerManager layerMana) {
		super.setLayer(layerMana);
		bullet.setLayer(layerMana);
	}

	public void logic() {
		super.logic();
		if (attackedFlag) {
			state = ENM_ATTACKED;
		}

		if (deadFlag) {
			state = ENM_DIE;
		}
		index = state;
		switch (state) {
		case ENM_WALK: {
			if (finding) {
				updateDirectX();
			} else {
				if (stopFlag) {
					if (stopTime-- < 0) {
						stopFlag = false;
						setState(tmpState);
						stopTime = 0;
					}
				} else {
					if (manDis < 0) {
						setDirect(DIR_RIGHT);
						posX += walkSpeed;
					} else {
						setDirect(DIR_LEFT);
						posX -= walkSpeed;
					}
				}
			}

			if (++frameNums[state] >= sprites[state].getFrameSequenceLength()) {
				updateLastFrame();
			} else {
				sprites[state].setFrame(frameNums[state]);
			}
			break;
		}
		case ENM_ATTACK: {
			switch (direct) {
			case DIR_LEFT: {
				posX -= Constants.ENM_ATTACK_MOVE_SPEED[type];
				break;
			}
			case DIR_RIGHT: {
				posY += Constants.ENM_ATTACK_MOVE_SPEED[type];
				break;
			}
			}

			if (++frameNums[state] >= sprites[state].getFrameSequenceLength()) {
				updateLastFrame();
				random.setSeed(System.currentTimeMillis());
				stop(random.nextInt(attackFreq), ENM_WALK);
				fire();
			} else {
				sprites[state].setFrame(frameNums[state]);
			}
			break;
		}
		case ENM_ATTACKED:
			switch (direct) {
			case DIR_LEFT: {
				posX += Constants.ENM_ATTACKED_AWAY_SPEED;
				break;
			}
			case DIR_RIGHT:
				posX -= Constants.ENM_ATTACKED_AWAY_SPEED;
				break;
			}

			if (++frameNums[state] >= sprites[state].getFrameSequenceLength()) {
				updateLastFrame();
				attackedFlag = false;
				stop(Constants.ENM_ATTACKED_DELAY, ENM_WALK);
				return;
			} else {
				sprites[state].setFrame(frameNums[state]);
			}
			break;
		case ENM_DIE: {
			if (++frameNums[state] >= sprites[state].getFrameSequenceLength()) {
				died = true;
				deadFlag = false;
				if (item != null) {
					item.setVisible(true);
					item.setPosition(posX + sprites[state].getWidth() / 2, Constants.ITEM_SHOW_H[item.getType()]);
					item.updateAllPositions();
				}
				for (int i = 0; i < totalState; i++) {
					sprites[i].setVisible(false);
				}
				return;
			} else {
				sprites[state].setFrame(frameNums[state]);
			}
			break;
		}
		}
		for (int i = 0; i < totalState; i++) {
			sprites[i].setVisible(false);
		}
		sprites[state].setVisible(true);
	}

	public int getAttackFreq() {
		return attackFreq;
	}

	private void updateLastFrame() {
		frameNums[state] = -1;
	}

	public void hurt(int drop) {
		blood -= drop;
		if (blood <= 0) {
			deadFlag = true;
		} else {
			attackedFlag = true;
		}
	}

	public void setFinding(boolean finding) {
		this.finding = finding;
	}

	public void setManDis(int manDis) {
		this.manDis = manDis;
	}
	
	public void createItem(int type, LayerManager layer) {
		if (type != -1) {
			item = new Item(type);
			item.setLayer(layer);
			item.setVisible(false);
		}
	}

	public Item getItem() {
		return item;
	}
}
